#ifndef FOREST_THREAD_LOCK_H__
#define FOREST_THREAD_LOCK_H__

#include "Platform.h"

#if defined(FOREST_PLATFORM_WINDOWS)
#include <windows.h>
#elif defined(FOREST_PLATFORM_LINUX)
#include <pthread.h>
#endif

//--------------LockInterface----------------
//-------------------------------------------
class IThreadLock
{
public:
	virtual ~IThreadLock(){};

	virtual void Lock() const = 0;
	virtual void Unlock() const = 0;
};


//------------Win32 CriticalSection----------
//-------------------------------------------
#if defined(FOREST_PLATFORM_WINDOWS)
class CCriSecLock : public IThreadLock
{
public:
	CCriSecLock();
	virtual ~CCriSecLock();

public:
	virtual void Lock() const;
	virtual void Unlock() const;

private:
	CRITICAL_SECTION* m_pCS;
};
#endif


//------------------ThreadMutex--------------
//-------------------------------------------
class CMutexLock : public IThreadLock
{
public:
	CMutexLock();
	virtual ~CMutexLock();

public:
	virtual void Lock() const;
	virtual void Unlock() const;

private:
#if defined(FOREST_PLATFORM_WINDOWS)
	HANDLE m_Mutex;
#elif defined(FOREST_PLATFORM_LINUX)
	mutable pthread_mutex_t m_Mutex;
#endif
};



//------------------ScopeLock----------------
//-------------------------------------------
class CScopeLock
{
public:
	CScopeLock(const IThreadLock*);
	~CScopeLock();

private:
	const IThreadLock* m_pThreadMutex;
};


template <class T = IThreadLock>
class TScopeLock
{
public:
	TScopeLock(const T* pThreadLock)
		: m_pThreadLock(pThreadLock)
	{
		if(m_pThreadLock)
		{
			m_pThreadLock->Lock();
		}
	}

	~TScopeLock()
	{
		if(m_pThreadLock)
		{
			m_pThreadLock->Unlock();
		}
	}

private:
	const T* m_pThreadLock;
};

#endif
